<?php
/**
 * Предок контроллера сообществ. Членство в сообществах, создание и изменений свойств сообществ
 *
 * @package default
 * @author Alexander Sibiryakov
 **/
abstract class Handler_Community extends RL_Handler
{
	public $aa; // acl_assistant
	
	public $model; // Model_Community
	public $acl_data;
	public $operations;
	
	public function init()
	{
		$this->aa = $this->module->aa;
		$this->acl_data = $this->aa->getInfo();
		$this->operations = $this->aa->getAvailableOperations();
		
		$this->model = $this->ctx->mm->getModel("Community", "m");
	}
	
	// создаст сообщество и копирует в него дефолтные роли, назначает модератора
	public function createCommunity( $info, $upload ) {

		$community_config = $this->model->default_config;
		
		// делаем init виджетов чтобы получить из них дефолтный конфиг
		$this->widgets_init( $community_config );
		
		$comm = $this->model->createCommunity($info, $community_config, $upload);

		if ($this->aa->createCommunity($comm->id, $comm->data['title']) > 0) {
			return $comm;
		}
		return false;
	}

	private function widgets_init(array $config) {
		foreach ($config['widgets'] as &$w) {
			$wi = widgets_create($w['name'], NULL);
			$w['params']['title'] = $wi->getParam('title');
		}		
	}

	/**
	 * Изменить сообщество.
	 *
	 * @param mixed $community_oid oid сообщества
	 * @param array $info данные (в $obj->data)
	 * @param array $upload $_FILES -- различные файлы, связанные с сообществом (картинки всякие)
	 * @access public
	 * @return fcommunity
	*/		
	public function changeCommunity( $community, $info, $upload, $delete_image = array())	{
		if (empty($community)) { /* community not found */ return false; }

		$operations = $this->aa->getAvailableOperations($community->id);
		if ( !$this->aa->is_granted( array( "community_edit") ) ) return false;

		$this->model->changeCommunity(&$community, $info, $upload, $delete_image);
		
		// добавим события каждому объекту, об изменении его URL адреса
		$this->addEventToAllItems("change_item_url", $community->id);
		$this->addEventToAllComments("change_item_url", $community->id);		
		$this->ctx->logger->flushLog();
		
		return $community;
	}
		
	private function addEventToAllItems($event_name, $comity_oid) {
		$prefix = $this->ctx->db->db_prefix;
		$rs = $this->ctx->store->findSQL(
		"SELECT {$prefix}objects.*, ao.openid FROM {$prefix}objects
		INNER JOIN {$prefix}class_allfeed af ON af.oid = {$prefix}objects.oid
		INNER JOIN {$prefix}class_user u ON u.oid = af.posted_by_id
		INNER JOIN {$prefix}class_auth_openid ao ON ao.oid = u.oid
		WHERE af.community_oid = ".$comity_oid);
		
		while ($fitem = $rs->next()) {
			$row = $rs->rs->current();
			$this->ctx->logger->event(new Event(time(), $event_name, $row['openid'], $fitem->id));
		}
		
	}
		
	private function addEventToAllComments($event_name, $comity_oid) {
		$prefix = $this->ctx->db->db_prefix;
		$rs = $this->ctx->store->findSQL(
		"SELECT {$prefix}objects.*, ao.openid, af.oid as item_oid FROM {$prefix}objects
		INNER JOIN {$prefix}class_comment c ON c.oid = {$prefix}objects.oid
		INNER JOIN {$prefix}class_allfeed af ON af.oid = c.item_oid
		INNER JOIN {$prefix}class_user u ON u.oid = af.posted_by_id
		INNER JOIN {$prefix}class_auth_openid ao ON ao.oid = u.oid
		WHERE af.community_oid = ".$comity_oid." AND {$prefix}objects.is_deleted = 0"
		);
		
		while ($fc = $rs->next()) {
			$row = $rs->rs->current();
			$this->ctx->logger->event(new Event(time(), $event_name, $row['openid'], $fc->id));
		}		
	}
	
	/**
	 * Присоединить пользователя в сообщество. Возвращаемые значения: 
	 * 0 - присоединен, 1 - заявка на рассмотрении, 2 - ошибка, не присоединен
	 *
	 * @return void
	 * @author Alexander Sibiryakov
	 **/
	public function joinCommunity( $community_oid, $user_oid, $role_name='member' )	{
		if (!isset($community_oid) || empty($user_oid) || empty($role_name))
		{
			error(__METHOD__."($community_oid, $user_oid, $role_name)");
			return 2;
		}
		
		// проверим режим вступления в сообщество
		$config = $this->ctx->mm->getModel("Community", "m")->getConfig($community_oid);
		
		if ($config['join_mode']=='moderated') {
			$jq = $this->ctx->mm->getModel("JoinQueue", "m");
			$jq->setCommunity($community_oid);
			if (!$jq->inQueue($user_oid)) $jq->addToQueue($user_oid);
			
			return 1;
			
		} elseif ($config['join_mode']=='free') {
			$role_name = strtolower($role_name);

			$c['role']['name']['=='] = $role_name;
			$rs = $this->ctx->store->find($c);
			$role = $rs->next();
			if ($this->aa->joinCommunity($community_oid, $role->id, $user_oid) > 0) {
				$member_model = $this->ctx->mm->getModel("Member");
				$member = $member_model->createMember($user_oid, $community_oid);
				$member_model->setJoinDate($member);
				if ($member_model->saveMember($member)) return 0;
			}
			
		}
		
		return 2;
		
	}
	
	/**
	 * Удалить юзера из сообщества
	 *
	 * @param mixed $community_oid сообщество
	 * @param mixed $user_oid юзер
	 * @access public
	 * @return boolean true если пользователь был в сообществе, или false если небыл или возникла ошибка
	*/	
	public function leaveCommunity ($community_oid, $user_oid) {
		if (!isset($community_oid) || !isset($user_oid))
		{
			error(__METHOD__."($community_oid, $user_oid)");
			return false;
		}

		$community_oid = isset($community_oid) ? $community_oid : $this->acl_data['comity_oid'];
		$user_oid      = isset($user_oid)      ? $user_oid      : $this->acl_data['user_id'];

		$store = $this->ctx->store;

		if ($this->aa->leaveCommunity($community_oid, $user_oid)) {
			// перенести в модель пользователя			
			$member_model = $this->ctx->mm->getModel("Member");
			if ($member_model->removeMember($user_oid, $community_oid)) {
				return true;
			}
		}
		return false;
	} // end of function leaveCommunity
	
	/**
	 * Удаление сообщества.
	 *
	 * @return boolean
	 * @param int $comity_oid 
	 * @author Alexander Sibiryakov
	 **/
	public function deleteCommunity($comity_oid) {
		$rs = $this->ctx->store->find( "objects where community.oid=:0 limit 0,1", array($comity_oid) );
		if (!rs) return false;
		
		$obj = $rs->next();
		$obj->is_deleted = 1;
		$obj->save();		
		
		// удалим сообщество из acl таблиц
		$result = $this->aa->delete( $obj->id );
		if ($result) {
			$this->addEventToAllItems("delete_item", $comity_oid);
			$this->addEventToAllComments("delete_comment", $comity_oid);
		}
		
		return $result;
	}	

	public function redirectToCommunity ($msg='', $o_community = NULL)
	{
		if ($msg) {
			$this->rh->setMessage($msg);
		}
		// для проголосовавших редирект на страницу итема
		$this->rh->UseClass('RL_URLGenerator');
		$ug = new RL_URLGenerator($this->rh->router->getRule('community'));
		$ug->setRouter($this->rh->router);
		$ug->setParams(array(
			'community_url' => isset($o_community) ? $o_community->data['community_url'] : $this->params['community_url'],
		));
		$url = $ug->generateUrl();
		if ($url) {
			$this->rh->redirect($url);
		} else {
			$this->rh->response->setContent( "Wazzup?!" );
		}
	} // end of method redirectToItem
	
} // END class 
